package ba05_After;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @author HLF
 * @version V1.0
 * @package ba01
 * @date 2021/10/17 10:19
 * @Aspect 是aspectj框架的注解，表示当前类是切面类
 * 切面类：用来给业务方法增加功能的类，在这个类中有增加切面功能的代码
 * 位置：在切面类定义的上面
 */
@Aspect
@Component//创建切面类对象
public class MyAspect {

    /**
     * 定义方法，方法是实现切面功能的。
     * 方法的定义要求：
     *      1.公共方法 public
     *      2.方法没有返回值
     *      3.方法名称自定义
     *      4.方法无固定参数，也可以有，是JoinPoint类型参数
     */
    /**
     * @After :最终通知
     *    属性： value 切入点表达式
     *    位置： 在方法的上面
     * 特点：
     *  1.总是会执行
     *  2.在目标方法之后执行的
     *
     *  try{
     *      SomeServiceImpl.doThird(..)
     *  }catch(Exception e){
     *
     *  }finally{
     *      myAfter()
     *  }
     *
     */


    @After(value = "doThird()")
    public void myAfter(JoinPoint joinPoint){
        System.out.println("最终通知：无论什么时候都会执行：");
        //一般是做资源清除工作的
    }

    @Before(value = "doThird()")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知：执行目标方法之前通知：");
    }

    /**
     * @Pointcut: 定义和管理切入点， 如果你的项目中有多个切入点表达式是重复的，可以复用的。
     *            可以使用@Pointcut
     *    属性：value 切入点表达式
     *    位置：在自定义的方法上面
     * 特点：
     *   当使用@Pointcut定义在一个方法的上面 ，此时这个方法的名称就是切入点表达式的别名。
     *   其它的通知中，value属性就可以使用这个方法名称，代替切入点表达式了
     */
    @Pointcut(value = "execution(* *..SomeServiceImpl.doThird(..))")
    private void doThird(){
        //无需代码
    }

}
